package com.mrduan.calculator.ui.calculator.base;

import android.view.View;

import com.mrduan.calculator.Config;
import com.mrduan.calculator.R;
import com.mrduan.calculator.utils.calculator.MathExtend;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

/**
 * Created by snoopy on 2018/4/10.
 */

public class CalculatorHandler {

    private View mView;

    public List<CalculatorBean> inputArray = new ArrayList<>();
    public CalculatorBean inputBean = new CalculatorBean();

    private CalculatorListener mListener;

    public CalculatorHandler(View view) {
        mView = view;

        initData();
        initWeight();
    }

    public CalculatorHandler(View view,CalculatorListener listener) {
        mView = view;
        mListener = listener;

        initData();
        initWeight();
    }

    private void initData() {
        if (!inputBean.loadBean(mView.getContext())) {
            inputBean.def();
        }
    }

    /**
     *
     */
    private void initWeight() {

        // 监听数字输入
        OnClickNumber clickNumber = new OnClickNumber();
        getViewWidthTag(R.string.yi).setOnClickListener(clickNumber);
        getViewWidthTag(R.string.er).setOnClickListener(clickNumber);
        getViewWidthTag(R.string.san).setOnClickListener(clickNumber);
        getViewWidthTag(R.string.si).setOnClickListener(clickNumber);
        getViewWidthTag(R.string.wu).setOnClickListener(clickNumber);
        getViewWidthTag(R.string.liu).setOnClickListener(clickNumber);
        getViewWidthTag(R.string.qi).setOnClickListener(clickNumber);
        getViewWidthTag(R.string.ba).setOnClickListener(clickNumber);
        getViewWidthTag(R.string.jiu).setOnClickListener(clickNumber);
        getViewWidthTag(R.string.ling).setOnClickListener(clickNumber);

        // 监听加、等于和点
        OnClickOperator clickOperator = new OnClickOperator();
        getViewWidthTag(R.string.deng).setOnClickListener(clickOperator);
        getViewWidthTag(R.string.dian).setOnClickListener(clickOperator);
        getViewWidthTag(R.string.jia).setOnClickListener(clickOperator);

        // 监听退格
        getViewWidthTag(R.string.back).setOnClickListener(new OnClickBack());

        // 监听支付方式
        OnClickWay clickWay = new OnClickWay();
        getViewWidthTag(R.string.zhifubao).setOnClickListener(clickWay);
        getViewWidthTag(R.string.weixin).setOnClickListener(clickWay);
        getViewWidthTag(R.string.ka).setOnClickListener(clickWay);
        getViewWidthTag(R.string.xianjin).setOnClickListener(clickWay);

    };


    /**
     * 设置监听
     *
     * @param mListener
     */
    public void setmListener(CalculatorListener mListener) {
        this.mListener = mListener;
    }


    /**
     * 点击数字
     */
    private class OnClickNumber implements View.OnClickListener {
        @Override
        public void onClick(View v) {
            if (inputBean.operator.equals(Config.dengyu)) {
                inputArray.add(new CalculatorBean(inputBean));
                inputBean.def();
            } else {
                if (inputBean.number.equals("0")) {
                    inputBean.number = v.getTag().toString();
                } else {
                    inputBean.number += v.getTag();
                }
            }
            showInput();
        }
    }

    /**
     * 点击操作符  加、等于和点
     */
    private class OnClickOperator implements View.OnClickListener{
        @Override
        public void onClick(View v) {
            // 点击的操作符是 {.}
            if (v.getTag().toString().equals(".")) {
                if (inputBean.operator.indexOf(".") == -1) {
                    if (inputBean.number.length() == 0) {
                        inputBean.number = "0";
                    }
                    inputBean.number += v.getTag();

                    showInput();
                }
            } else if (v.getTag().toString().equals(Config.dengyu)){
                if (getLastCount().size() == 0 && (inputBean.number.equals("0") || inputBean.number.equals(""))) {} else if(inputBean.operator.equals(Config.dengyu)) {} else {
                    if (canCount()) {
                        // 点击操作符后保存当前的输入项
                        saveInput();
                    }

                    inputBean.def(inputBean.result,Config.dengyu);

                    mListener.upView(inputArray,inputBean);
                }
            } else {
                if (inputBean.number.length() > 0/*如果没有数字，直接更新操作符就可以*/ && canCount()/*输入的数字符合计算法则*/) {
                    // 保存输入值
                    saveInput(inputBean.operator,inputBean.number,inputBean.payWay);
                }

                inputBean.def();
                inputBean.operator = v.getTag().toString();
            }

        }
    }

    /**
     * 点击退格键
     */
    private class OnClickBack implements View.OnClickListener{
        @Override
        public void onClick(View v) {
            if (inputBean.number.length() > 0) {
                inputBean.number = inputBean.number.substring(0,inputBean.number.length() - 1);

                if (inputBean.operator.equals("")){
                    inputBean.number = "0";
                }

            } else {
                if (inputBean.operator.equals("")){
                    inputBean.number = "0";
                } else {
                    inputBean.operator = "";
                    if (inputArray.size() > 0) {
                        // 加载数据到显示位置
                        inputBean = inputArray.get(inputArray.size() - 1);
                        // 删除数据库中的数据
                        mListener.dataBaseDelete(inputBean);
                        // 删除列表中的数据
                        inputArray.remove(inputArray.get(inputArray.size() - 1));
                        mListener.doDelete(inputBean);
                    }
                }
            }

            showInput();
        }
    }

    /**
     * 点击支付方式
     */
    private class OnClickWay implements View.OnClickListener{
        @Override
        public void onClick(View v) {
            inputBean.payWay = v.getTag().toString();
            mListener.upView(inputArray,inputBean);
        }
    }

/*--------------------核心算法-------------------------------------------------------*/

    /**
     * 开始运算列表
     */
    private void yunSuan() {
        //循环当前所有内容，提取需要使用的

        List<CalculatorBean> needUseArray = getLastCount();

        if (inputArray.size() != 0) {
            // 开始计算
            List<CalculatorBean> saves = new ArrayList<>();

            for (int i = 0;i < needUseArray.size() + 1;i++) {

                CalculatorBean bean = null;

                if (i == needUseArray.size()) {
                    if (inputBean.number.equals(""))
                        break;
                    bean = new CalculatorBean(inputBean);
                } else {
                    bean = new CalculatorBean(needUseArray.get(i));
                }

                if (i==0) {
                    saves.add(bean);
                    continue;
                }
                CalculatorBean save = saves.get(saves.size() -1);

                saves.add(bean);
            }

            // 运算加减
            for (CalculatorBean bean : saves) {
                if (bean.operator.equals(Config.jia)) {
                    inputBean.result = MathExtend.add(inputBean.result,bean.number);
                } else if (bean.operator.equals(Config.jian)) {
                    inputBean.result = MathExtend.subtract(inputBean.result,bean.number);
                } else {
                    inputBean.result = bean.number;
                }
            }
        }

        inputBean.result = remove0(inputBean.result);
    }

    /**
     * 取出最后一组计算
     *
     * @return
     */
    private List<CalculatorBean> getLastCount() {
        List<CalculatorBean> lastCountArray = new ArrayList<>();

        for (int i = inputArray.size()-1;i>=0;i--) {
            CalculatorBean arg = inputArray.get(i);
            if (arg.operator.equals(Config.dengyu)) {
                break;
            }
            lastCountArray.add(0,arg);
        }

        return lastCountArray;
    }

    /**
     * 删除小数点后的无用零
     *
     * @param result
     * @return
     */
    public String remove0(String result) {
        while (result.indexOf(".") != -1) {
            String s = result.substring(result.length() - 1);
            if (s.equals("0") || s.equals(".")) {
                if (result.length() - 1 > 0)
                    result = result.substring(0,result.length() - 1);
                else
                    result = "0";
            } else {
                break;
            }
        }
        return result;
    }


/*--------------------核心算法------END-------------------------------------------------*/


    /**
     * 显示当前输入数字 并计算所有结果
     */
    private void showInput() {

        if (canCount()) {
            yunSuan();
        }
        mListener.upView(inputArray,inputBean);
    }

    /**
     * 判断当前值是否能够被运算
     *
     * @return
     */
    private boolean canCount() {
        if (inputBean.number.indexOf(".") != -1) {
            String arg[] = inputBean.number.split("\\.");
            if (arg.length!=2 || arg[1].length() == 0) {
                return  false;
            }
        }

        return true;
    }

    /**
     * 当前输入的是操作符，且之前输入的操作符是等号
     * 保存当前操作符，拷贝之前结果
     */
    private void needSaveAndCopy() {
        if (inputBean.operator.equals(Config.dengyu)) {
            saveInput("",inputBean.number,inputBean.payWay);
            inputBean.def(inputBean.result);
            mListener.upView(inputArray,inputBean);
        }
    }


    /**
     * 保存当前输入内容
     */
    private void saveInput() {
        // 保存到列表
        saveInput(inputBean.operator,inputBean.number,inputBean.payWay);
    }
    /**
     * 保存输入内容到 数据库和列表
     *
     * @param op
     * @param number
     * @param way
     */
    public void saveInput(String op,String number,String way){

        inputArray.add(new CalculatorBean(number,inputBean.operator,number, way, Calendar.getInstance().getTimeInMillis()));

        mListener.doSave(inputBean);

        // 保存到数据库
        mListener.dataBaseSave(inputBean);
    }


    /**
     * 绑定控件
     * @param id
     * @param <E>
     * @return
     */
    private final <E extends View> E getViewWidthTag(int id) {
        try {

            return (E) mView.findViewWithTag(mView.getContext().getResources().getString(id));

        } catch (Exception e) {

            e.printStackTrace();

            return null;

        }
    }

}
